﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SettingsStringSerializer.cs" company="DevDigital">
//   DevDigital
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Settings.NET.Serializers
{
    using System;

    /// <summary>
    /// Settings - string serializer
    /// Provides simple serialization/deserialization to strings
    /// </summary>
    [Serializable]
    public class SettingsStringSerializer : ISettingsSerializer
    {
        /// <summary>
        /// Serializes the specified value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="value">The value.</param>
        /// <returns>The serialized value</returns>
        public string Serialize<TValue>(TValue value)
        {          
            return (object)value == null ? null : value.ToString();
        }

        /// <summary>
        /// Deserializes the specified value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="value">The value.</param>
        /// <returns>The deserialized value</returns>
        public TValue Deserialize<TValue>(string value)
        {
            try
            {
                if (typeof(TValue).IsEnum)
                {
                    return (TValue)Enum.Parse(typeof(TValue), value);
                }              

                if (typeof(TValue) == typeof(TimeSpan))
                {
                    var convertedValue = TimeSpan.Parse(value);
                    return (TValue)(object)convertedValue;
                }

                if (ConversionHelper.IsNullableType<TValue>())
                {
                    var type = typeof(TValue);
                    var underlyingType = Nullable.GetUnderlyingType(type);
                    var convertedValue = Convert.ChangeType(value, underlyingType);
                    return (TValue)convertedValue;
                }

                return (TValue)Convert.ChangeType(value, typeof(TValue));
            }
            catch
            {
                return default(TValue);
            }
        }        
    }
}